Conversation
Adds a real tests/ suite so the project no longer relies on doctests alone: - tests/test_runner.py runs each built-in filter over its own example.tex end to end, asserting on the returned Set and on the JSON/ZIP written to disk. - [tool.pytest.ini_options] collects both tests/ and the package doctests, so a bare `pytest` covers everything. - CI: `black .` -> `black --check .` (no longer silently reformats), and isort/pydocstyle now also cover tests/. Applies black to two pre-existing files (visibility_status.py, json_convert.py) that were not clean under `black --check`. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017VXb8aZqgFBjoeuuddjW6r
New in2lambda.validation package that checks the #/## markdown contract for
unbalanced or misplaced KaTeX math delimiters before conversion:
- validation/delimiters.py: math_delimiter_checker() scans markdown char by
char and returns a MathDelimiterError enum member (PASSED on success).
- validation/__init__.py: check_markdown() aggregates checks into a list of
problems, ready to be surfaced as warnings by the Markdown filter and the
wizard.
Ported from conversion2025/tools and testing/{validator,validator_classes}.py
on the Summer2025 branch; the sentinel exception classes are replaced with an
enum. All of that branch's validator_tests.py cases are ported to
tests/test_validation.py.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017VXb8aZqgFBjoeuuddjW6r
|
Some notes from reviewing this before merge. I ran the checker from this branch (Python 3.11) on a few short samples rather than reading it alone. Nothing here is a blocker. A from in2lambda.validation import math_delimiter_checker as chk
chk("Run `echo $PATH` now.\n") # INVALID_NEWLINE_INSIDE_INLINE
chk("```bash\necho $HOME\n```\n") # INVALID_NEWLINE_INSIDE_INLINEAny question that shows a shell command or a code sample gets a warning it shouldn't. Skipping code spans and fenced blocks before scanning would fix it. (Prices are fine, by the way: The message for an unclosed No location, and only the first problem. The checker returns one enum for the whole document, so on a file of twenty questions you learn that something is wrong somewhere. Returning a list of messages with line numbers would make it actionable, and would let the caller print all of them. Tracking the line is only a few lines of code given the loop already walks the string. One documentation point. |
A `$` inside inline code (`echo $PATH`) or a fenced code block was previously treated as a math delimiter, misreporting shell variables and code samples as broken math. Track fence/code-span state in the scanner and skip delimiter checks while inside one. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Previously the checker returned a single MathDelimiterError enum for the whole document, stopping at the first problem, and misreported an unclosed inline "$" as INVALID_NEWLINE_INSIDE_INLINE whenever a newline appeared before end of input. math_delimiter_checker/check_markdown now return list[MathDelimiterProblem], each carrying a 1-based line number, and resync after an error to keep scanning for further independent problems instead of stopping at the first. The newline-inside-inline check is removed entirely: an unclosed "$ ... $" is always reported as MISSING_CLOSING_SINGLE_DOLLAR regardless of embedded newlines, and (as a consequence) a multi-line "$ ... $" that does eventually close is no longer flagged as an error. PASSED is dropped from the enum since "no problem" is now represented by an empty list. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The module docstring attributed this formatting rule to KaTeX itself; it's actually just this project's authoring convention. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
pydocstyle (D105) was failing CI lint for the magic method missing a docstring. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Following up on my last point above, to correct it before anyone acts on it. I said the
f"\n\n$$\n{expression}\n$$\n\n"with What's actually wrong is only the attribution in Suggested reword: say the check matches the output format in2lambda emits ( |
|
Updated to better handle $ inside code, by specifically searching for code environments. Updated error handling to report line number and file. Made it clearer that $$ on a new line is our convention. |
New
in2lambda.validationpackage that checks the#/##markdown contract for unbalanced or misplaced KaTeX math delimiters before conversion.validation/delimiters.py:math_delimiter_checker()scans markdown char by char and returns aMathDelimiterErrorenum member (PASSEDon success).validation/__init__.py:check_markdown()aggregates checks into a list of problems, ready to be surfaced as warnings by the Markdown filter and the wizard.conversion2025/toolsandtesting/{validator,validator_classes}.pyonSummer2025; sentinel exception classes replaced with an enum. All of that branch'svalidator_tests.pycases ported totests/test_validation.py.Stack: test-harness ← validator ← markdown-filter ← …
Base:
test-harness— review/merge #21 first.🤖 Generated with Claude Code